/**
 * 关注关系数据模型
 * @author HalRui
 * @version 1.0.0
 * @description 基于Mongoose的关注关系数据模型，定义用户关注关系的数据结构和操作方法
 * @date 2025年9月27日
 */

const mongoose = require('mongoose');

// 关注ID计数器模型，用于生成自动增长的关注ID
const FollowIdCounterSchema = new mongoose.Schema({
    _id: { type: String, required: true },
    sequence_value: { type: Number, default: 0 }
});

const FollowIdCounter = mongoose.model('FollowIdCounter', FollowIdCounterSchema);

const followSchema = new mongoose.Schema({
    followId: { // 独立的自动增长关注ID，从1开始递增
        type: Number,
        unique: true,
        index: true,
        description: "独立的自动增长关注ID"
    },
    followerId: { // 关注者用户ID
        type: Number,
        required: [true, "关注者ID不能为空"],
        index: true,
        description: "关注者用户ID"
    },
    followingId: { // 被关注者用户ID
        type: Number,
        required: [true, "被关注者ID不能为空"],
        index: true,
        description: "被关注者用户ID"
    },
    status: { // 关注状态：1-正常关注，0-已取消关注
        type: Number,
        enum: [0, 1],
        default: 1,
        index: true,
        description: "关注状态：1-正常关注，0-已取消关注"
    },
    isDeleted: { // 软删除标记，默认为false
        type: Boolean,
        default: false,
        index: true,
        description: "是否已删除（软删除）"
    },
    deletedAt: { // 删除时间
        type: Date,
        description: "删除时间"
    },
    createAt: { // 关注时间
        type: Date,
        default: Date.now,
        description: "关注时间"
    },
    updateAt: { // 更新时间
        type: Date,
        default: Date.now,
        description: "更新时间"
    }
}, {
    versionKey: false // 禁用 __v
});

// 创建复合索引，确保同一用户不能重复关注同一个人
followSchema.index({ followerId: 1, followingId: 1 }, { unique: true });

// 保存前的中间件：自动生成followId和更新时间
followSchema.pre('save', async function(next) {
    try {
        // 如果是新文档且没有followId，则生成自增ID
        if (this.isNew && !this.followId) {
            const counter = await FollowIdCounter.findByIdAndUpdate(
                'followId',
                { $inc: { sequence_value: 1 } },
                { new: true, upsert: true }
            );
            this.followId = counter.sequence_value;
        }
        
        // 更新updateAt时间
        this.updateAt = new Date();
        next();
    } catch (error) {
        next(error);
    }
});

// 静态方法：创建关注关系
followSchema.statics.createFollow = async function(followerId, followingId) {
    try {
        // 检查是否自己关注自己
        if (followerId === followingId) {
            return {
                success: false,
                message: "不能关注自己"
            };
        }

        // 检查是否已经关注过
        const existingFollow = await this.findOne({
            followerId,
            followingId,
            isDeleted: false
        });

        if (existingFollow) {
            if (existingFollow.status === 1) {
                return {
                    success: false,
                    message: "已经关注过该用户"
                };
            } else {
                // 重新关注
                existingFollow.status = 1;
                existingFollow.updateAt = new Date();
                await existingFollow.save();
                return {
                    success: true,
                    message: existingFollow
                };
            }
        }

        // 创建新的关注关系
        const newFollow = new this({
            followerId,
            followingId
        });

        await newFollow.save();
        return {
            success: true,
            message: newFollow
        };
    } catch (error) {
        return {
            success: false,
            message: error.message
        };
    }
};

// 静态方法：取消关注
followSchema.statics.unfollow = async function(followerId, followingId) {
    try {
        const follow = await this.findOne({
            followerId,
            followingId,
            status: 1,
            isDeleted: false
        });

        if (!follow) {
            return {
                success: false,
                message: "未关注该用户"
            };
        }

        follow.status = 0;
        follow.updateAt = new Date();
        await follow.save();

        return {
            success: true,
            message: "取消关注成功"
        };
    } catch (error) {
        return {
            success: false,
            message: error.message
        };
    }
};

// 静态方法：检查关注状态
followSchema.statics.checkFollowStatus = async function(followerId, followingId) {
    try {
        const follow = await this.findOne({
            followerId,
            followingId,
            status: 1,
            isDeleted: false
        });

        return {
            success: true,
            message: {
                isFollowing: !!follow,
                followInfo: follow
            }
        };
    } catch (error) {
        return {
            success: false,
            message: error.message
        };
    }
};

// 静态方法：获取关注列表
followSchema.statics.getFollowingList = async function(userId, page = 1, limit = 20) {
    try {
        const skip = (page - 1) * limit;
        
        const follows = await this.find({
            followerId: userId,
            status: 1,
            isDeleted: false
        })
        .sort({ createAt: -1 })
        .skip(skip)
        .limit(limit);

        const total = await this.countDocuments({
            followerId: userId,
            status: 1,
            isDeleted: false
        });

        return {
            success: true,
            message: {
                follows,
                pagination: {
                    page,
                    limit,
                    total,
                    pages: Math.ceil(total / limit)
                }
            }
        };
    } catch (error) {
        return {
            success: false,
            message: error.message
        };
    }
};

// 静态方法：获取粉丝列表
followSchema.statics.getFollowersList = async function(userId, page = 1, limit = 20) {
    try {
        const skip = (page - 1) * limit;
        
        const followers = await this.find({
            followingId: userId,
            status: 1,
            isDeleted: false
        })
        .sort({ createAt: -1 })
        .skip(skip)
        .limit(limit);

        const total = await this.countDocuments({
            followingId: userId,
            status: 1,
            isDeleted: false
        });

        return {
            success: true,
            message: {
                followers,
                pagination: {
                    page,
                    limit,
                    total,
                    pages: Math.ceil(total / limit)
                }
            }
        };
    } catch (error) {
        return {
            success: false,
            message: error.message
        };
    }
};

// 静态方法：获取用户关注统计
followSchema.statics.getFollowStats = async function(userId) {
    try {
        const followingCount = await this.countDocuments({
            followerId: userId,
            status: 1,
            isDeleted: false
        });

        const followersCount = await this.countDocuments({
            followingId: userId,
            status: 1,
            isDeleted: false
        });

        return {
            success: true,
            message: {
                followingCount,
                followersCount
            }
        };
    } catch (error) {
        return {
            success: false,
            message: error.message
        };
    }
};

// 静态方法：批量检查关注状态
followSchema.statics.batchCheckFollowStatus = async function(followerId, followingIds) {
    try {
        const follows = await this.find({
            followerId,
            followingId: { $in: followingIds },
            status: 1,
            isDeleted: false
        });

        const followingMap = {};
        follows.forEach(follow => {
            followingMap[follow.followingId] = true;
        });

        const result = followingIds.map(id => ({
            userId: id,
            isFollowing: !!followingMap[id]
        }));

        return {
            success: true,
            message: result
        };
    } catch (error) {
        return {
            success: false,
            message: error.message
        };
    }
};

// 实例方法：获取安全的JSON数据
followSchema.methods.getSafeJSON = function() {
    const obj = this.toObject();
    delete obj._id;
    return obj;
};

module.exports = mongoose.model('Follow', followSchema);